using System.Runtime.InteropServices;
using System.Xml;
using ICSharpCode.TextEditor.Formatting.TSqlFormatter.Formatters;
using ICSharpCode.TextEditor.Formatting.TSqlFormatter.Interfaces;
using ICSharpCode.TextEditor.Formatting.TSqlFormatter.Parsers;
using ICSharpCode.TextEditor.Formatting.TSqlFormatter.Tokenizers;

namespace ICSharpCode.TextEditor.Formatting.TSqlFormatter
{
    [Guid("A7FD140A-C3C3-4233-95DB-A64B50C8DF2B")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComVisible(true)]
    [ProgId("PoorMansTSqlFormatter.SqlFormattingManager")]
    public class SqlFormattingManager : _SqlFormattingManager
    {
        public ISqlTokenizer Tokenizer { get; set; }

        public ISqlTokenParser Parser { get; set; }

        public ISqlTreeFormatter Formatter { get; set; }

        public SqlFormattingManager()
            : this(new TSqlStandardTokenizer(), new TSqlStandardParser(), new TSqlStandardFormatter())
        {
        }

        public SqlFormattingManager(ISqlTreeFormatter formatter)
            : this(new TSqlStandardTokenizer(), new TSqlStandardParser(), formatter)
        {
        }

        public SqlFormattingManager(ISqlTokenizer tokenizer, ISqlTokenParser parser, ISqlTreeFormatter formatter)
        {
            Tokenizer = tokenizer;
            Parser = parser;
            Formatter = formatter;
        }

        public string Format(string inputSQL)
        {
            bool errorEncountered = false;
            return Format(inputSQL, ref errorEncountered);
        }

        public string Format(string inputSQL, ref bool errorEncountered)
        {
            XmlDocument xmlDocument = Parser.ParseSQL(Tokenizer.TokenizeSQL(inputSQL));
            errorEncountered = xmlDocument.SelectSingleNode(string.Format("/{0}/@{1}[.=1]", "SqlRoot", "errorFound")) != null;
            return Formatter.FormatSQLTree(xmlDocument);
        }

        public static string DefaultFormat(string inputSQL)
        {
            return new SqlFormattingManager().Format(inputSQL);
            
        }

        public static string DefaultFormat(string inputSQL, ref bool errorsEncountered)
        {
            return new SqlFormattingManager().Format(inputSQL, ref errorsEncountered);
        }
    }
}
